#include <GL/glut.h>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include "objectmanager.h"
#include "objobject.h"
#include "common.h"
#include "objanim.h"

ObjectManager::ObjectManager() {

}

ObjectManager::~ObjectManager() {

}

OBJObject* ObjectManager::createOBJObject(std::string filename, std::string uniqName) {
	if (filename.size() == 0) {
		ERROR("ObjectManager::createOBJObject(): filename is empty!");
		return 0;
	}
	if (!isUnique(uniqName)) {
		ERROR("ObjectManager::createOBJObject(): chosen uniqName is NOT unique!");
		return 0;
	}

	m_objobjectList.push_back(new OBJObject);
	m_objobjectList.back()->analyzeFile(filename);
	m_objobjectList.back()->loadFile(filename);
	m_objobjectList.back()->setUniqName(uniqName);
	if (m_objobjectList.back()->m_texturefilename.size()>0) {
		myTextureManager->getTexture(m_objobjectList.back()->m_texturefilename);
		glEnable(GL_TEXTURE_2D);
	}

	return m_objobjectList.back();
}

OBJAnim* ObjectManager::createOBJAnim(std::string filename, std::string uniqName) {
	char tempstr[10];
	if (filename.size() == 0) {
		ERROR("ObjectManager::createOBJAnim(): filename is empty!");
		return 0;
	}
	if (!isUniqueAnim(uniqName)) {
		ERROR("ObjectManager::createOBJAnim(): chosen uniqName is NOT unique!");
		return 0;
	}
	
	m_objAnimList.push_back(new OBJAnim);
	m_objAnimList.back()->setUniqName(uniqName);

	std::string::size_type strFound;
	std::string origfilename = filename;
	
	//find first occurence of '#'
	strFound = filename.find_first_of("#", 0);
	 std::cout << "original filename: " << filename << std::endl;
	 std::cout << "strFound # at: " << strFound << std::endl;


	for (int i=1; i <= MAX_OBJANIM_NUM; i++) {
//	for (int i=1; i <= 5; i++) {
		//generate strings in the format 000001 i.e. lenght 6 filled up with zeroes
		sprintf(tempstr, "%06u", i);
	
		//replace # with string 00000x 
		filename.replace(strFound, 1, tempstr, 0, 6);

		FILE *file;
		//if file exists
		if ((file = fopen(filename.c_str(), "r"))!=NULL)
		{
			//create objects here:
			std::cout << "altered filename: " << filename << std::endl;
			(m_objAnimList.back()->m_objobjectList).push_back(new OBJObject);
			(m_objAnimList.back()->m_objobjectList).back()->analyzeFile(filename);
			(m_objAnimList.back()->m_objobjectList).back()->loadFile(filename);
			/** \todo each frame has the same unique name! */
			(m_objAnimList.back()->m_objobjectList).back()->setUniqName(uniqName);
			(m_objAnimList.back()->m_objobjectList).back()->frameNum = i;
			
//			if (m_objAnimList.back()->m_objobjectList.back()->m_texturefilename.size()>0) {
//				myTextureManager->getTexture(m_objAnimList.back()->m_objobjectList.back()->m_texturefilename);
//				glEnable(GL_TEXTURE_2D);
//			}
	
		}
		else {
			m_objAnimList.back()->m_numFrames = i-1;
			std::cout << "last objanim filename index was: " 
				<< m_objAnimList.back()->m_numFrames << std::endl;
			break;
		}
		
		filename = origfilename;
	}
	return (m_objAnimList.back());
}

int ObjectManager::isUnique(std::string uniqueName) {
	int notfound = 1;	
	std::list<OBJObject*>::iterator it;
	for (it=m_objobjectList.begin(); it!=m_objobjectList.end(); it++) {
		//unique identifier is NOT unique!
		if (uniqueName == (*it)->m_uniqName) {
			LOG("ObjectManager: OBJObject is NOT unique!");
			notfound = 0;
		}
	}
	return notfound;
}

int ObjectManager::isUniqueAnim(std::string uniqueName) {
	int notfound = 1;	
	std::list<OBJAnim*>::iterator it;
	for (it=m_objAnimList.begin(); it!=m_objAnimList.end(); it++) {
		//unique identifier is NOT unique!
		if (uniqueName == (*it)->m_uniqName) {
			LOG("ObjectManager: OBJAnim is NOT unique!");
			notfound = 0;
		}
	}
	return notfound;
}

void ObjectManager::drawObject(std::string uniqueName) {
	int found = 0;
	std::list<OBJObject*>::iterator it;
	for (it=m_objobjectList.begin(); it!=m_objobjectList.end(); it++) {
		//Object found!
		if (uniqueName == (*it)->m_uniqName) {
			LOG("ObjectManager::drawObject(): OBJObject found!");
			found = 1;
			(*it)->drawObject();
		}
	}
	if (found == 0) ERROR("ObjectManager::drawObject(): OBJObject  " << uniqueName << "  couldn't be found"); 
}

OBJObject* ObjectManager::findObject(std::string uniqueName) {
	int found = 0;
	std::list<OBJObject*>::iterator it;
	for (it=m_objobjectList.begin(); it!=m_objobjectList.end(); it++) {
		//Object found!
		if (uniqueName == (*it)->m_uniqName) {
			LOG("ObjectManager::findObject(): OBJObject found!");
			found = 1;
			return (*it);
		}
	}
	if (found == 0) {
		ERROR("ObjectManager::findObject(): OBJObject  " << uniqueName << "  couldn't be found"); 
		return 0;
	}
	return 0;
}


OBJAnim* ObjectManager::findAnimObject(std::string uniqueName) {
	int found = 0;
	std::list<OBJAnim*>::iterator it;
	for (it=m_objAnimList.begin(); it!=m_objAnimList.end(); it++) {
		//Object found!
		if (uniqueName == (*it)->m_uniqName) {
			LOG("ObjectManager::findAnimObject(): OBJAnim found!");
			found = 1;
			return (*it);
		}
	}
	if (found == 0) {
		ERROR("ObjectManager::findAnimObject(): OBJAbnim  " << uniqueName << "  couldn't be found"); 
		return 0;
	}
	return 0;
}


//not used anymore
OBJObject* ObjectManager::getOBJObject(std::string filename) {
	int objectfound = 0;
	if (filename.size() == 0) {
		ERROR("getOBJObject(): filename is empty!");
		return 0;
	}
	std::list<OBJObject*>::iterator it;
	LOG("number of textureList elements: " << m_objobjectList.size());
	
	//there are already some OBJObjects
	if (m_objobjectList.size()>0) {
		LOG("ObjectManager: m_objobjectList is NOT empty! searching for requested OBJObject...");
		for (it=m_objobjectList.begin(); it!=m_objobjectList.end(); it++) {
	//		LOG("address: " << *it << " m_id: " << (*it)->m_id);

			//right OBJObject found!
			if (filename == (*it)->m_objobjectFilename) {
				LOG("ObjectManager: requested OBJObject found!");
				objectfound = 1;
				return *it;
			}
		}
		//that particular OBJObject couldn't be found
		if (objectfound == 0) {
			LOG("ObjectManager: OBJObject couldn't be found! Creating it..."); 
			//so we have to create it
			m_objobjectList.push_back(new OBJObject);
			m_objobjectList.back()->analyzeFile(filename);
			m_objobjectList.back()->loadFile(filename);
			if (m_objobjectList.back()->m_texturefilename.size()>0) {
				myTextureManager->getTexture(m_objobjectList.back()->m_texturefilename);
				glEnable(GL_TEXTURE_2D);
			}

			//load the texture file
//			m_objobjectList.back()->loadGLTextures(filename);
			//and return the pointer to the Texture
			return m_objobjectList.back();
		}
	}
	//if m_objobjectList is completely empty
	else {
		LOG("ObjectManager: No OBJObjects found at all! Creating it..."); 
		//we have to create a new OBJObject
		m_objobjectList.push_back(new OBJObject);
		
		m_objobjectList.back()->analyzeFile(filename);
		m_objobjectList.back()->loadFile(filename);
		if (m_objobjectList.back()->m_texturefilename.size()>0) {
			myTextureManager->getTexture(m_objobjectList.back()->m_texturefilename);
			glEnable(GL_TEXTURE_2D);
		}
		//load the texture file
//		m_objobjectList.back()->loadGLTextures(filename);
		//and return the pointer to the Texture
		return m_objobjectList.back();
	}
	//we should never get here so we return 0
	return 0;
}

